Skip to content

Conversation

@0xrinegade
Copy link
Member

@0xrinegade 0xrinegade commented May 23, 2025

Summary by Sourcery

Fix highlight.js loading errors by adding a resilient script loader with fallbacks and reordering initialization; overhaul page structure and styling with CSS variables, a collapsible sidebar, and responsive design; introduce interactive features such as live search, chapter navigation, code copy/execute buttons, and PDF/print controls.

New Features:

  • Add robust script loader with primary and fallback CDNs for highlight.js, marked.js, and DOMPurify
  • Introduce dynamic chapter sidebar navigation with expand/collapse and responsive toggling
  • Implement full-text search across chapters with real-time filtering
  • Add copy and execute buttons for code blocks including shell commands
  • Enable PDF download and print controls for the document

Bug Fixes:

  • Fix highlight.js initialization error by polling for library load before app initialization

Enhancements:

  • Refactor page layout and styling using CSS variables and custom themes in place of Tailwind
  • Overhaul CSS for improved table, code block, and ASCII diagram presentation
  • Improve error handling and logging during script loading and syntax highlighting
  • Streamline markdown rendering with sanitization and custom marked.js renderer

Documentation:

  • Add documentation file for highlight.js library loading and initialization fixes

@sourcery-ai
Copy link

sourcery-ai bot commented May 23, 2025

Reviewer's Guide

This PR introduces a robust script loader with fallback sources and DOMContentLoaded-driven initialization to resolve highlight.js load errors, implements a custom marked renderer that handles ASCII diagrams and injects copy/execute buttons in code blocks, refactors CSS into a variable-driven, responsive layout with a dynamic sidebar and search, and adds a documentation file detailing the highlight.js fix.

Sequence Diagram for Robust Script Loading

sequenceDiagram
    participant B as Browser
    participant LS as loadScript Function
    participant CDN1 as Primary CDN
    participant CDN2 as Fallback CDN

    B->>LS: Call loadScript(primarySrc, fallbackSrc, callback)
    LS->>CDN1: Request script from primarySrc
    alt Script loads from Primary CDN
        CDN1-->>LS: Script loaded successfully
        LS->>B: Execute callback()
    else Primary CDN fails
        LS-->>CDN1: Error loading script
        LS->>CDN2: Request script from fallbackSrc
        alt Script loads from Fallback CDN
            CDN2-->>LS: Script loaded successfully
            LS->>B: Execute callback()
        else Fallback CDN fails
            LS-->>CDN2: Error loading script
            LS->>B: Log error "Failed to load script from fallback source"
        end
    end
Loading

Sequence Diagram for App Initialization and Chapter Loading

sequenceDiagram
    participant U as User
    participant DOM as Browser DOM
    participant App as JS Application
    participant MSrc as Markdown Source (Cache/Fetch)
    participant Marked as marked.js (with Custom Renderer)
    participant HLJS as highlight.js
    participant DP as DOMPurify

    U->>DOM: Loads page
    DOM-->>App: DOMContentLoaded event
    App->>App: initializeApp(): Check library readiness (hljs, marked, DOMPurify)
    opt Libraries not ready
        App->>App: Wait and recheck
    end
    App->>App: initApp(): Setup UI (sidebar, etc.)
    App->>App: loadChapter(chapterId)
    App->>MSrc: Request chapter content
    MSrc-->>App: Return markdown string
    App->>Marked: parse(markdownString)
    Marked->>HLJS: (via custom renderer) Highlight code
    HLJS-->>Marked: Highlighted code fragments
    Marked-->>App: Return HTML string
    App->>DP: sanitize(htmlString)
    DP-->>App: Return sanitized HTML
    App->>DOM: Update chapter content area
    App->>DOM: Update sidebar (subchapters, active links)
Loading

Class Diagram for Client-Side Application Modules

classDiagram
    class App {
        +chapters: Array
        +markdownCache: Object
        +currentChapterId: String
        +initializeApp()
        +initApp()
        +loadChapter(chapterId)
        +updateNavigationButtons()
        +updateSubchapters(chapterId, contentElement)
        +initializeSidebar()
        +toggleSubchapters(chapterId)
        +search(query)
        +addToSearchIndex(chapterId, title, content)
    }
    class ScriptLoader {
        +loadScript(src, fallbackSrc, callback)
    }
    class CustomMarkedRenderer {
        +code(code, language): string
        +table(header, body): string
    }
    class UIEventListeners {
        +handleSidebarToggle()
        +handleDownloadPDF()
        +handlePrintPage()
        +handleSearchInput()
        +handleKeyboardShortcuts()
        +copyCode(button)
        +executeCode(button)
    }
    class ExternalLibraries {
      <<Service>> highlight.js
      <<Service>> marked.js
      <<Service>> DOMPurify
    }
    App --> ScriptLoader : uses
    App --> CustomMarkedRenderer : configures marked.js with
    App --> UIEventListeners : manages
    CustomMarkedRenderer ..> ExternalLibraries : uses highlight.js
    App ..> ExternalLibraries : uses marked.js, DOMPurify
    ScriptLoader ..> ExternalLibraries : loads
Loading

File-Level Changes

Change Details Files
Robust library loading and initialization
  • Added a generic loadScript(src, fallback, callback) helper for highlight.js, marked.js, and DOMPurify
  • Wrapped app bootstrap in DOMContentLoaded and polling to defer until all libraries load
  • Logged successes and errors for primary and fallback script loads
index.html
Custom markdown renderer with enhanced code blocks
  • Extended marked.Renderer.code to detect ASCII diagrams vs. code
  • Injected copy and execute buttons into
     blocks
  • Configured marked options for sanitization and syntax highlighting fallback
index.html
Dynamic sidebar navigation and search
  • Built a collapsible chapter sidebar from a chapters array
  • Implemented live search index on headings and paragraphs
  • Added keyboard shortcuts and navigation controls (prev/next, toggle sidebar)
index.html
CSS refactor and visual enhancements
  • Replaced legacy monospace styles with CSS variables and responsive rules
  • Overhauled table, card, info‐box, ASCII diagram, and button styling
  • Introduced sidebar, content layout, and media queries for mobile
index.html
Documentation for highlight.js fix
  • Added fixed_hljs_documentation.md with issue summary and root causes
  • Outlined implemented solutions: script loader, init sequence, error handling, renderer tweaks
fixed_hljs_documentation.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@0xrinegade 0xrinegade requested a review from Copilot May 23, 2025 22:31
@netlify
Copy link

netlify bot commented May 23, 2025

Deploy Preview for aeamcp ready!

Name Link
🔨 Latest commit 952c94c
🔍 Latest deploy log https://app.netlify.com/projects/aeamcp/deploys/6830f71c6cef940008839cde
😎 Deploy Preview https://deploy-preview-2--aeamcp.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the documentation to explain how the highlight.js loading error was fixed and how visual elements (code blocks, ASCII diagrams, buttons) were enhanced.

  • Adds robust script loading with CDNs and fallbacks
  • Describes improved initialization and error handling sequences
  • Documents rendering logic for code blocks, diagrams, and interactive buttons
Comments suppressed due to low confidence (1)

fixed_hljs_documentation.md:113

  • The documentation references copyCode and executeCode handlers but doesn’t specify their implementation or imports; consider adding a note or snippet showing how these functions should be defined.
html += '<button class="copy-button" onclick="copyCode(this)">Copy</button>';

}
};
document.head.appendChild(script);
}
Copy link

Copilot AI May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a short example immediately after the loadScript function showing how to call it for each library (e.g., loadScript(primaryUrl, fallbackUrl, initializeApp);) so integrators know how to actually use this loader.

Suggested change
}
}
// Example usage of loadScript
loadScript(
'https://cdn.jsdelivr.net/npm/[email protected]/lib/highlight.min.js', // Primary URL
'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js', // Fallback URL
function() {
console.log('highlight.js loaded successfully');
// Initialize the app or perform actions requiring highlight.js
if (typeof hljs !== 'undefined') {
hljs.highlightAll();
} else {
console.error('highlight.js is not available');
}
}
);

Copilot uses AI. Check for mistakes.
html += ` class="language-${language}"`;
}

html += `>${hljs.highlightAuto(code, language ? [language] : undefined).value}</code></pre>`;
Copy link

Copilot AI May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Suggest calling hljs.highlightElement (used earlier in this doc) when a specific language is known, as highlightAuto can misidentify languages and may be slower on large blocks.

Copilot uses AI. Check for mistakes.
Copy link

@devloai devloai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary:

This PR transforms the static documentation into an interactive dynamic system with features like:
• Dynamic chapter loading from markdown files
• Collapsible sidebar with search functionality
• Enhanced code blocks with copy/execute buttons
• Responsive design and improved styling
• Robust script loading with CDN fallbacks

Review Summary:

I identified 4 critical issues that need to be addressed before this PR can be merged. The main problems are a logic error in highlight.js usage that causes conflicts, missing markdown files that break the core functionality, a security risk in the code execution feature, and an incorrect PDF download path. I utilized my knowledge of the repository structure and JavaScript best practices to perform this review. Please provide feedback on this review which I will take into account for future reviews.

Follow-up suggestions:

@devloai fix the identified issues in the comments
@devloai create the missing markdown files by splitting the existing documentation

html += ` class="language-${language}"`;
}

html += `>${hljs.highlightAuto(code, language ? [language] : undefined).value}</code></pre>`;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical Logic Error in highlight.js Usage

The code is calling hljs.highlightAuto() inside the marked renderer's code function (line 724), but this creates a chicken-and-egg problem. The marked renderer is executed when marked.parse() is called, which happens before highlight.js has had a chance to process the code blocks. This will result in immediate execution of highlight.js during markdown parsing, potentially before the DOM is ready and certainly before hljs.highlightElement() is called later.

Issues:

  1. hljs.highlightAuto() returns an object with a .value property, but it's being used as if it returns a string
  2. This approach bypasses the normal highlighting flow and may cause conflicts
  3. The code blocks will be highlighted twice - once during markdown parsing and once during DOM processing

Solution:

Suggested change
html += `>${hljs.highlightAuto(code, language ? [language] : undefined).value}</code></pre>`;
html += `>${code}</code></pre>`;

Remove the hljs.highlightAuto() call here and let the normal highlighting process in hljs.highlightElement() handle syntax highlighting after the DOM is ready.

{ id: "11", title: "Future Directions", file: "research_draft_part11.md" },
{ id: "12", title: "Conclusion", file: "research_draft_part12.md" },
{ id: "13", title: "References", file: "research_draft_part13.md" },
{ id: "14", title: "Appendices", file: "research_draft_part14.md" }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded Chapter Configuration Doesn't Match Actual Content

The application is hardcoded to load 14 specific markdown files (research_draft_part1.md through research_draft_part14.md), but based on the repository structure, these files don't exist. The actual repository contains:

  • index.html (this file)
  • draft.rs (Rust smart contract)
  • README.md (project documentation)
  • aeamcp.pdf
  • preview.png
  • fixed_hljs_documentation.md

Problems:

  1. All chapter loading will fail with 404 errors
  2. The search functionality won't work as there's no content to index
  3. Users will see error messages for missing files

Solution:
Either:

  1. Create the expected markdown files by splitting the existing documentation
  2. Or modify the chapter configuration to use existing content like README.md and draft.rs
  3. Or implement a fallback to load content from the existing static documentation structure

// This is a simplified approach - in a real environment,
// you would need to use a more sophisticated method to open a terminal
const terminal = window.open('', '_blank');
if (terminal) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Risk: Arbitrary Code Execution via Popup

The executeCode function opens a new window and writes arbitrary content to it using document.write(). This creates several security concerns:

Issues:

  1. XSS Risk: If code contains malicious HTML/JavaScript, it will be executed in the new window
  2. Popup Blockers: Modern browsers will likely block this popup
  3. User Experience: Opening random popups is poor UX and may be flagged as malicious

Solution:

function executeCode(button) {
    const pre = button.closest('pre');
    const code = pre.querySelector('code');
    const command = code.textContent.trim();
    
    // Safely copy to clipboard and show instructions
    navigator.clipboard.writeText(command).then(() => {
        alert(`Command copied to clipboard:\n\n${command}\n\nPlease paste and execute in your terminal.`);
    }).catch(err => {
        // Fallback for unsupported browsers
        alert(`Please copy and execute this command in your terminal:\n\n${command}`);
    });
}

This approach is safer and provides better user experience.

// Download PDF
downloadPDFButton.addEventListener('click', () => {
// Open PDF in new tab
window.open('solana_protocol_design_for_agent_and_mcp_server_registries.pdf', '_blank');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect PDF Download Path

The download PDF functionality references 'solana_protocol_design_for_agent_and_mcp_server_registries.pdf' but the actual PDF file in the repository is named aeamcp.pdf.

Problem:

  • Users will get a 404 error when trying to download the PDF
  • The functionality will appear broken

Solution:

Suggested change
window.open('solana_protocol_design_for_agent_and_mcp_server_registries.pdf', '_blank');
window.open('aeamcp.pdf', '_blank');

Update the path to match the actual file in the repository.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @0xrinegade - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟡 General issues: 5 issues found
  • 🟢 Security: all looks good
  • 🟢 Review instructions: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

<!-- Load libraries in the correct order with fallbacks -->
<script>
// Function to load script with fallback
function loadScript(src, fallbackSrc, callback) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Handle permanent load failures to prevent infinite retry loop

Add a maximum retry limit or an abort flag to stop retries when both sources fail.

code = typeof code === 'string' ? code : String(code);

// Check if this is an ASCII diagram
const isAsciiDiagram = code.includes('+-') || code.includes('|') || code.includes('--') || code.includes('==') || code.includes('[]');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): ASCII diagram detection may misclassify generic code

Consider using an explicit language marker (e.g., ```ascii) or a front-matter flag to identify diagrams, rather than relying on character patterns that may misclassify regular code.

currentChapterId = chapterId;
}

// Update active state in sidebar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Avoid changing 'active' link when only toggling subchapter list

Move the 'active' class update inside the content loading logic or separate the toggle and content update logic to keep the sidebar state consistent with the displayed chapter.

</head>
<body>
<div class="container">
<button id="sidebarToggle" class="sidebar-toggle"></button>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Add ARIA attributes to sidebar toggle for accessibility

Add aria-expanded, aria-controls, and an aria-label to the toggle button to improve screen reader accessibility.

Suggested change
<button id="sidebarToggle" class="sidebar-toggle"></button>
<button id="sidebarToggle" class="sidebar-toggle" aria-expanded="false" aria-controls="sidebar" aria-label="Toggle sidebar"></button>

</style>
</head>
<body>
<div class="container">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use semantic tags (e.g.

, ) instead of generic

Wrap the main content in a

element and use for navigation to improve accessibility and structure.

Suggested implementation:

<body>

    <header>
        <button id="sidebarToggle" class="sidebar-toggle">☰</button>
        <!-- Place navigation or branding here if needed -->
    </header>
    <main class="container">

    <!-- External libraries with fallback mechanisms -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-gist.min.css">

    <!-- Load libraries in the correct order with fallbacks -->
    <script>
        // Function to load script with fallback
        function loadScript(src, fallbackSrc, callback) {
            var script = document.createElement('script');
            script.src = src;
            script.onload = callback;

You will need to:

  • Move any other main content that was inside the .container div into the new <main class="container"> element.
  • Ensure that the <main> and <header> tags are properly closed at the appropriate places in the file.
  • If there is navigation or branding, move it into the <header>.

@0xrinegade 0xrinegade requested a review from Copilot May 23, 2025 23:58
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants